package com.zykj.thread.concurrent.lock.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhoulj(周利军) [1217102780@qq.com]
 * @Module ID:   <(模块)类编号，可以引用系统设计中的类编号>
 * @Comments: <对此类的描述，可以引用系统设计中的描述>
 * @JDK version used:      <JDK1.8> 43
 * @since 2019/1/14-14:43
 */
//TODO 面试题：condition 多条件判断与通信》》 main 循环10 再给 sub循环5次， 再给sub3 循环两次 再交给main 循环10次 以此50次
public class ThreadSubFor2 {
    public static void main(String[] args) {
        final ThreadSub threadSub = new ThreadSub();
        new Thread((Runnable)() -> {
            for (int i = 0; i < 50; i++) {
                threadSub.sub(i);
            }
        }).start();

        new Thread((Runnable)() -> {
            for (int i = 0; i < 50; i++) {
                threadSub.sub2(i);
            }
        }).start();
        for (int i = 0; i < 50; i++) {
            threadSub.main(i);

        }

    }


    //TODO 总结：锁或线程同步控制  不是放在同步代码块中 而是放在资源内部的
    static class ThreadSub {
        int subrun = 1;
        Lock lock = new ReentrantLock();
        Condition sub = lock.newCondition();
        Condition sub3 = lock.newCondition();
        Condition main = lock.newCondition();
        public void main(int maini) {
//        if (subrun) {
            lock.lock();
            try {
                while(subrun!=1) { //TODO 这里使用while 语义更好， 防止伪唤醒
                    try {
                        main.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int i = 0; i < 10; i++) {
                    System.out.println("这是主线程：i="+maini+", j=" + (i+1));
                }
                subrun = 2;
                sub.signal();
            }finally {
                lock.unlock();

            }

        }
        public void sub(int maini) {
//        if (!subrun) {
            lock.lock();
            try {
                while (subrun!=2) {
                    try {
                        sub.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int j = 0; j < 5; j++) {
                    System.out.println("这是子线程：i="+maini+", j=" + (j+1));
                }
                subrun = 3;
                sub3.signal();
            }finally {
                lock.unlock();
            }

        }

        public void sub2(int maini) {
//        if (!subrun) {
            lock.lock();
            try {
                while (subrun!=3) {
                    try {
                        sub3.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                for (int j = 0; j < 3; j++) {
                    System.out.println("***这是第二子线程：i="+maini+", j=" + (j+1));
                }
                subrun = 1;
                main.signal();
            }finally {
                lock.unlock();
            }

        }
    }
}

